﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace WindowsFormsApplication1
{
    class KeyboardValidator : IValidator
    {

        public Dictionary<string, Tuple<User,int>> compare(User user, List<User> usersList)
        {
            Dictionary<string, Tuple<User, int>> comparison = new Dictionary<string, Tuple<User, int>>();
            
            if (usersList.Count < 0)
            {
                return comparison;
            }

            // Sprawdz porownanie dla alt-tab
            int AllAverageAltTabUsage = 0;
            User AverageAltTabUsage = null;
            foreach (User u in usersList)
            {
                AllAverageAltTabUsage += u.KeyStats.AverageAltTabUsage;
                if (AverageAltTabUsage!=null)
                {
                    if (Math.Abs(u.KeyStats.AverageAltTabUsage - user.KeyStats.AverageAltTabUsage) < Math.Abs(user.KeyStats.AverageAltTabUsage - AverageAltTabUsage.KeyStats.AverageAltTabUsage))
                    {
                        AverageAltTabUsage = u;
                    }
                }
                else
                {
                    AverageAltTabUsage = u;
                }
            }
            comparison["AverageAltTabUsage"] = new Tuple<User, int>(AverageAltTabUsage, AllAverageAltTabUsage);

            // Sprawdz porownanie dla backspace
            int AllAverageBackspaceUsage = 0;
            User AverageBackspaceUsage = null;
            foreach (User u in usersList)
            {
                AllAverageBackspaceUsage += u.KeyStats.AverageBackspace;
                if (AverageBackspaceUsage!=null)
                {
                    if (Math.Abs(u.KeyStats.AverageBackspace - user.KeyStats.AverageBackspace) < Math.Abs(user.KeyStats.AverageBackspace - AverageBackspaceUsage.KeyStats.AverageBackspace))
                    {
                        AverageBackspaceUsage = u;
                    }
                }
                else
                {
                    AverageBackspaceUsage = u;
                }
            }
            comparison["AverageBackspaceUsage"] = new Tuple<User, int>(AverageBackspaceUsage, AllAverageBackspaceUsage);

            // Sprawdz porownanie dla entera
            int AllAverageEnterUsage = 0;
            User AverageEnterUsage = null;
            foreach (User u in usersList)
            {
                AllAverageEnterUsage += u.KeyStats.AverageEnterUsage;
                if (AverageEnterUsage!=null)
                {
                    if (Math.Abs(u.KeyStats.AverageEnterUsage - user.KeyStats.AverageEnterUsage) < Math.Abs(user.KeyStats.AverageEnterUsage - AverageEnterUsage.KeyStats.AverageEnterUsage))
                    {
                        AverageEnterUsage = u;
                    }
                }
                else
                {
                    AverageEnterUsage = u;
                }
            }
            comparison["AverageEnterUsage"] = new Tuple<User, int>(AverageEnterUsage, AllAverageEnterUsage);

            return comparison;
        }

        public string validate(string keysDeserialized, string newKey)
        {
            Console.WriteLine("Nacisniete klawisze: " + newKey);
            string[] splitedNewKey = newKey.Split(' ');

            string[] lines = Regex.Split(keysDeserialized, "\r\n");
            int bestMatchDiff = 9999999;
            string bestMatchLogin = "";

            Dictionary<string, int> userKeysOcc = new Dictionary<string, int>();
            foreach (string key in splitedNewKey)
            {
                if (key.Equals(""))
                    continue;
                //update number of occurences by one
                if (userKeysOcc.ContainsKey(key))
                {
                    int num;
                    userKeysOcc.TryGetValue(key, out num);
                    num++;
                    userKeysOcc.Remove(key);
                    userKeysOcc.Add(key, num);
                }
                else
                {
                    // add to dictionary 
                    userKeysOcc.Add(key, 1);
                }
            }
            Console.WriteLine("Czestotliwosc wystepowania:");
            foreach (string key in userKeysOcc.Keys)
            {
                int num;
                userKeysOcc.TryGetValue(key, out num);
                Console.WriteLine(key + " : " + num);
            }

            string login = "walidowanyUzytkownik";
            foreach (string line in lines)
            {
                if (line.Length == 0)   // if empty string then we don't count it
                    continue;

                // Console.WriteLine("Linia: " + line);
                string[] wordsInLine = line.Split(' ');
                string currentLogin = wordsInLine[0].Substring(0, wordsInLine[0].Length - 1);

                Dictionary<string, int> savedUserKeysOcc = new Dictionary<string, int>();
                foreach (string keys in wordsInLine)
                {
                    if (keys.Equals("") || keys[keys.Length - 1].Equals(':'))
                        continue;
                    //update number of occurences by one

                    if (savedUserKeysOcc.ContainsKey(keys))
                    {
                        int num;
                        savedUserKeysOcc.TryGetValue(keys, out num);
                        num++;
                        savedUserKeysOcc.Remove(keys);
                        savedUserKeysOcc.Add(keys, num);
                    }
                    else
                    {
                        // add to dictionary 
                        savedUserKeysOcc.Add(keys, 1);
                    }
                }

                int currentDiff = 0;

                // now compare
                Console.WriteLine("Klawisze "+ currentLogin + " : "  + line);
                foreach (string keys in userKeysOcc.Keys)
                {

                    if (savedUserKeysOcc.ContainsKey(keys))
                    {
                        int num;
                        savedUserKeysOcc.TryGetValue(keys, out num);
                        int num2;
                        userKeysOcc.TryGetValue(keys, out num2);
                        currentDiff += Math.Abs(num - num2);
                        Console.WriteLine("Obaj nacisneli :  " + keys + " , roznica ilosci klikniec: " + Math.Abs(num - num2) + ", roznica calkowita : " + currentDiff);
                    }
                    else
                    {
                        int num2;
                        userKeysOcc.TryGetValue(keys, out num2);
                        currentDiff += num2;
                        Console.WriteLine("Tylko " + login + " nacisnal:  " + keys + " , ilosc nacisniec: " + num2 + ", roznica calkowita : " + currentDiff);
                    }
                }

                foreach (string keys in savedUserKeysOcc.Keys)
                {
                    if (userKeysOcc.ContainsKey(keys))
                    {
                        continue;
                    }
                    else
                    {
                        int num;
                        savedUserKeysOcc.TryGetValue(keys, out num);
                        currentDiff += num;
                        Console.WriteLine("Jedynie " + currentLogin + " nacisnal: " + keys + "  ilosc nacisniec: " + num + ", roznica calkowita : " + currentDiff);
                    }
                }
                Console.WriteLine(login + "/" + currentLogin + ": calkowita roznica: " + currentDiff);
                if (currentDiff == bestMatchDiff)
                {
                    bestMatchDiff = currentDiff;
                    bestMatchLogin += (" " + wordsInLine[0].Substring(0, wordsInLine[0].Length - 1));
                }
                else if (currentDiff < bestMatchDiff)
                {
                    bestMatchDiff = currentDiff;
                    bestMatchLogin = wordsInLine[0].Substring(0, wordsInLine[0].Length - 1);
                }

            }

            Console.WriteLine("Najmniejsza roznica nacisnietych klawiszy: " + bestMatchDiff + ", uzytkownik: " + bestMatchLogin);
                return bestMatchLogin;
        }
    }
}
